// data interpolated from vertex program output
struct vertexIN
{
	float2 refractCoords		: TEXCOORD0;
	float2 reflectCoords		: TEXCOORD1;
	float2 bumpCoords			: TEXCOORD2;
	float3 objectSpacePos		: TEXCOORD3;
	float3 normal   			: TEXCOORD4;
};

float4 calcLights(
			in float3 position,
			in float3 normal,
			in float3 toEye,
			in float3 lightPosition[8],
			in float3 Ks,
			in float shininess)
{
	float4 result	= float4(0.0, 0.0, 0.0, 0.0);
		
	for (int i = 0; i < 8; i++)
	{
		float3 toLight	= normalize(position - lightPosition[i]);
		float3 halfway	= normalize(toEye + toLight);
		
		float4 lightVals = lit(dot(normal, toLight), dot(normal, halfway), shininess);
		
		result.xyz		+= lightVals.z*float3(1.0, 1.0, 1.0)*Ks;
		result.w		+= lightVals.z;
	}
	
	result = clamp(result, 0, 1);
	
	return result;
}

float4 main(vertexIN vIn, 
              uniform float4x4 modelViewInv,
              uniform float4x4 modelViewProj,
	          uniform float3 lightPosition[8],
              uniform float3 Ka,
              uniform float3 Kd,
              uniform float3 Ks,
              uniform float  shininess,
              uniform float3 waterNormal,
              uniform sampler2D refractionTexture,
     		  uniform sampler2D reflectionTexture,
			  uniform float distanceToRefraction,
			  uniform float distanceToReflection,
     		  uniform sampler2D bumpMap,
     		  uniform float2 bumpMapSize,
     		  uniform float2 bumpOrigin) : COLOR
{
	// The eye position in object space: 
	float3 eyePos = mul(modelViewInv, float4(0,0,0,1)).xyz;
	
	// The light positions in object space:
	float3 lightInObjectSpace[8];
	for (int i = 0; i < 8; i++)
	{
		lightInObjectSpace[i] = mul(modelViewInv, float4(lightPosition[i], 1.0)).xyz;
	}

	// The vector to the eye:
	float3 toEye = normalize(eyePos - vIn.objectSpacePos);

	vIn.bumpCoords = fmod(vIn.bumpCoords + bumpOrigin, 1.0);

	// The normal disturbed by the bump map:
	float3 bumpMapUnit;
	bumpMapUnit.xy = 1.0/bumpMapSize;
	bumpMapUnit.z = 0.0;

	float3 distortion;
	distortion.x 					= tex2D(bumpMap, vIn.bumpCoords - bumpMapUnit.xz).r
				  					- tex2D(bumpMap, vIn.bumpCoords + bumpMapUnit.xz).r;
	distortion.y 					= tex2D(bumpMap, vIn.bumpCoords - bumpMapUnit.zy).r
									- tex2D(bumpMap, vIn.bumpCoords + bumpMapUnit.zy).r;
	distortion.z					= 0.0;
	
	distortion					   /= 4.0;

	float3 normal = normalize(vIn.normal - distortion);

	float3 refractionVector			= refract(toEye, normal, 1.0/1.33);
	float4 refractionCameraSpace	= normalize(mul(modelViewProj, float4(refractionVector, 0.0)));
	float  distanceToEye			= length(eyePos - vIn.objectSpacePos);
	float2 refractionOffset			= refractionCameraSpace.xy/distanceToEye;
	vIn.refractCoords			   += distanceToRefraction*refractionOffset;
	
	float3 reflectionVectorIdeal	= normalize(reflect(toEye, waterNormal));
	float3 reflectionVector			= reflect(toEye, normal);
	float3 reflectionProjection		= distanceToReflection*(reflectionVector - dot(reflectionVector, reflectionVectorIdeal)*reflectionVectorIdeal);
	float2 reflectionOffset			= normalize(reflectionProjection.xy)*length(reflectionProjection);
	vIn.reflectCoords			   += reflectionOffset;

	float incomingAngle = min(degrees(acos(dot(normal, toEye)))/65.0, 1.0);
	
	float4 color;
	// The lower the incoming angle, the more reflection (linear interpolation):
	color = (1 - incomingAngle)*tex2D(refractionTexture, vIn.refractCoords)
		  + incomingAngle*tex2D(reflectionTexture, vIn.reflectCoords);

	float4 lightingColor = calcLights(
			vIn.objectSpacePos,
			normal,
			toEye,
			lightInObjectSpace,
			Ks,
			shininess);
			
//	color.xyz = 0.8*color.xyz + 0.2*lightingColor.xyz;
//	color.xyz = lightingColor.w*lightingColor.xyz + (1-lightingColor.w)*color.xyz;
	
	// Water is opague, we don't need no more effects.
	color.a = 1.0;

	return color;
}